#ifndef     __ERROR_H
#define     __ERROR_H

#include <stdint.h>

namespace utils {

namespace ec {

constexpr uint8_t Ok = 0x00;
constexpr uint8_t ParseFail = 0x01;
constexpr uint8_t Locked = 0x02;
constexpr uint8_t Timeout = 0x03;
constexpr uint8_t CargoNotFind = 0x04;
constexpr uint8_t CargoFull = 0x05;
constexpr uint8_t RobotArmNotAdj = 0x06;
constexpr uint8_t Ds18b20Fail = 0x07;
constexpr uint8_t ArgInvalid = 0x08;
constexpr uint8_t DrawFail = 0x09; // 吸取失败
constexpr uint8_t PositionFail = 0x0A;
constexpr uint8_t NotBegin = 0x0B; // 出货前 没有启动
constexpr uint8_t DropOut = 0x0C;// 物品掉落
constexpr uint8_t FlashCheckFail = 0x0D;
constexpr uint8_t FlashEraseFail = 0x0E;
constexpr uint8_t FlashFail = 0x0F;
constexpr uint8_t OtaIdInvalid = 0x10;
constexpr uint8_t OtaMd5SumFail = 0x11;

}

struct error_t {

    inline error_t() : err_code(ec::Ok) {}
    inline error_t(uint8_t ec): err_code(ec) {}
    inline error_t(const error_t& err) : err_code(err.err_code) {}

    inline error_t(uint16_t) = delete;
    inline error_t(uint32_t) = delete;

    inline error_t& operator=(uint8_t ec) {
        err_code = ec;
        return *this;
    }

    inline error_t& operator=(const error_t& err) {
        err_code = err.err_code;
        return *this;
    }

    inline uint32_t encode(uint8_t *b) const {
        *b = err_code;
        return 1;
    }

    inline operator uint8_t() const {
        return err_code;
    }

    inline bool operator==(const error_t err) const {
        return err_code == err.err_code;
    }
    inline bool operator ==(uint8_t ec) const {
        return err_code == ec;
    }

    inline bool operator!=(const error_t err) const {
        return err_code!= err.err_code;
    }
    inline bool operator!=(uint8_t ec) const {
        return err_code != ec;
    }

    inline operator bool() const {
        return err_code != ec::Ok;
    }

    inline bool is_ok() const {
        return err_code == ec::Ok;
    }

    uint8_t err_code;
};

}

#define IF_ERR_RETURN(err) \
    if (err) {  \
        return err; \
    }

#endif
